﻿
using System;
using System.Linq;
using System.Windows.Forms;
using DemoEF.Model;

namespace DemoEF
{
    /// <summary>
    /// Demo:
    /// + How to read and writing Database with CodeFisrt
    /// + Data audit in EF
    /// + Create Model in namespace Model
    /// </summary>
    public partial class CodeFirst : Form
    {
        private int _productId;
        public CodeFirst()
        {
            InitializeComponent();
            loadCategory();
            loadProduct();
        }

        private void btnAdd_Click(object sender, System.EventArgs e)
        {
            AddProduct((cbbCategory.SelectedItem.ToString()), txtProductName.Text);
        }

        private void btnLoadProduct_Click(object sender, System.EventArgs e)
        {
            loadProduct();
        }

        private void btnAddCategory_Click(object sender, System.EventArgs e)
        {
            AddCategory(txtCategory.Text);
        }

        private void AddProduct(string categoryId, string productName)
        {
            using (var db = new ProductDbContext())
            {
                var category = db.Categories.Find(int.Parse(categoryId));
                var product = new Product() { Name = productName, Category = category };

                db.Products.Add(product);
                var recordAffect = db.SaveChanges();
                lblLog.Text = string.Format("{0} is saved into Database", recordAffect);

                //load product
                var query = (from c in db.Products select c);
                gridViewProduct.DataSource = query.ToList();
            }
        }

        private void AddCategory(string categoryName)
        {
            using (var db = new ProductDbContext())
            {
                var category = new Category() { Name = categoryName };
                db.Categories.Add(category);

                //Demo Data validation
                var validationErrors = db.GetValidationErrors()
                                        .Where(vr => !vr.IsValid)
                                        .SelectMany(vr => vr.ValidationErrors).ToList();

                foreach (var error in validationErrors)
                {
                    MessageBox.Show(error.ErrorMessage);
                }
                if(!validationErrors.Any())
                {
                    var recordAffect = db.SaveChanges();
                    lblLog.Text = string.Format("{0} is saved into Database", recordAffect);
                }
                
                



                //load Categories
                loadCategory();
            }
        }
        //Load all product
        private void loadProduct()
        {
            using (var db = new ProductDbContext())
            {
                var query = (from c in db.Products select c);
                gridViewProduct.DataSource = query.ToList();
            }

        }
        private void loadCategory()
        {
            cbbCategory.Items.Clear();
            using (var db = new ProductDbContext())
            {
                foreach (var category in db.Categories)
                {
                    cbbCategory.Items.Add(category.CategoryId);
                }

            }
        }

        //Demo Data Audit
        private void Audit()
        {
            using (var db = new ProductDbContext())
            {
                var product = db.Products.Find(_productId);

                // Change value directly in the DB
                using (var contextDB = new ProductDbContext())
                {
                    contextDB.Database.ExecuteSqlCommand(
                        "UPDATE Products SET Name_Editted = Name_Editted + '_DB' WHERE ProductId = {0}", _productId);
                }

                product.Name += "_Memory";

                //Display
                lblDbvalue.Text = "Database Value: " + db.Entry(product).GetDatabaseValues().GetValue<string>("Name");
                lblOriginalValue.Text = "Original value: " + db.Entry(product).Property(s => s.Name).OriginalValue;
                lblCurrentValue.Text = "Current value: " + db.Entry(product).Property(s => s.Name).CurrentValue;
            }
        }

        private void btnAudit_Click(object sender, System.EventArgs e)
        {
            Audit();
        }


        private void gridViewProduct_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                var index = e.RowIndex;
                _productId = (int)gridViewProduct.Rows[index].Cells[0].Value;
            }
            catch (Exception)
            {
            }

        }

    }

}
